#pragma once
#include <QObject>
#include <QRectF>
#include <QVector>
#include <QPointer>

class QGraphicsItem;
class QGraphicsScene;

enum class SatellitePosition
{
    LEFT    = 0,
    TOP     = 1,
    RIGHT   = 2,
    BOTTOM  = 3
};

class SelectAdapter : public QObject
{
    Q_OBJECT
signals:
    // 对于SelectController来说
    // 输入信号，发出者是使用SelectAdapter的对象
    void requestSelectToken();
    void geometryChanged(QRectF geometry);

    // 输出信号，直接发出者是SelectController，但源发出者可能会追溯到SatelliteItem
    // 看p的值来决定调用哪个功能
    // 比如在从左到右生长的思维导图中，一个节点的BottomItem点击后，需要添加与该节点同级的节点
    // 而RightItem点击后，则需要在该该节点长出一个子节点
    void satelliteClicked(SatellitePosition p);
    void receiveSelectToken();

    // 成对的，output发出之后，可以在input中获取到返回值
    void requestGeometry(); // output
    void sendGeometry(QRectF geometry); // input
};

class SatelliteAdapter : public QObject
{
    Q_OBJECT
public:
    SatelliteAdapter(SatellitePosition p) : _p(p) {}
    SatellitePosition getSatellitePosition() { return _p; }

signals:
    // 从SelectController的角度看

    // 功能信号，p表示SatelliteItem所处的方位
    // 具体如何按方位分功能由SelectItem端来决定
    void clicked(SatellitePosition p);     // input
    void sendSelectToken();                // input
    void receiveGeometry(QRectF geometry); // output
    void invisible(bool yes);              // output

private:
    SatellitePosition _p;
};

class SelectController : public QObject
{
    Q_OBJECT
public:
    SelectController();
    void competitorRegister(SelectAdapter* adapter);
    void setScene(QGraphicsScene* scene);
    void setSatellite(SatelliteAdapter* adapter);
    void connectRequest();

public slots:
    // 用来检测用户是否点击空白区域
    void focusItemChanged(QGraphicsItem *newFocusItem, QGraphicsItem *oldFocusItem, Qt::FocusReason reason);

signals:
    void satellitesInvisible(bool yes);

private:
    QVector<QPointer<SatelliteAdapter>> _satellites;
    QPointer<SelectAdapter> _current_item;
    QPointer<SelectAdapter> _prev_item;
};
